package com.iqiyi.dbagent.contraller.impl;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.iqiyi.dbagent.base.config.CommParme.DEALBEFORE;
import com.iqiyi.dbagent.base.config.MySqlConfig;
import com.iqiyi.dbagent.base.config.i.Configuration;
import com.iqiyi.dbagent.base.i.IInitDataBase;
import com.iqiyi.dbagent.base.i.ISqlMonitorServer;
import com.iqiyi.dbagent.base.utils.data.DataSourceUtil;
import com.iqiyi.dbagent.base.utils.time.DateUtil;
import com.iqiyi.dbagent.contraller.i.DBAgentTemplate;
import com.iqiyi.dbagent.contraller.i.IDataStoreHandler;
import com.iqiyi.dbagent.model.DealAfter;
import com.iqiyi.dbagent.model.DealBefore;
import com.iqiyi.dbagent.model.Table4QiData;
import com.iqiyi.dbagent.view.monitor.alarm.Alarm;
import com.iqiyi.dbagent.view.monitor.alarm.SelfAlarm;

/**
 * @Title: DefaultDBAgentTemplate.java
 * @Package com.iqiyi.dbagent.contraller.impl
 * @author wangnianming
 * @Description: 默认分入库模板
 * @date 2015年11月19日 下午5:27:24
 * @version V1.0
 */
public class MysqlAgentTemplate implements DBAgentTemplate,IInitDataBase{

	/** 日志记录器 */
	private static final Logger logger = LoggerFactory.getLogger(MysqlAgentTemplate.class);

	public MysqlAgentTemplate() {
        // TODO Auto-generated constructor stub
    }

	/* (non-Javadoc)
	 * @see com.iqiyi.dbagent.contraller.i.DBAgentTemplate#dealBefore()
	 */
	public DealBefore dealBefore(Configuration config) {
	    DealBefore dbfore = new DealBefore();
	    dbfore.setInputPath(config.getInputPath());
	    dbfore.setOutpuPath(config.getOutputPath());
	    dbfore.setDealType(config.getDealtype());
		if(initDataBase(config))dbfore.setDealBrfore(DEALBEFORE.INITEDOK);
		return dbfore;
	}

	/* (non-Javadoc)
	 * @see com.iqiyi.dbagent.contraller.i.DBAgentTemplate#dealDataAsStreaming(java.io.InputStream, com.iqiyi.dbagent.base.config.Configuration, com.iqiyi.dbagent.contraller.i.IDataStoreHandler)
	 */
	public DealAfter dealDataAsStreaming(InputStream is, Configuration config,
			IDataStoreHandler handler,ISqlMonitorServer iMonitor) {
		logger.info("使用MysqlAgentTemplate,解析streaming的方式入库数据...");
		MySqlConfig myConfig = (MySqlConfig)config;
		DealBefore bfore = dealBefore(myConfig);
		DealAfter after = new DealAfter();
		after.setDealStartTime(new Date());
		BufferedReader bfr = new BufferedReader(new InputStreamReader(is,Charset.forName("UTF-8")));
		if(bfore.getDealBrfore() == DEALBEFORE.INITEDOK){
		    logger.info("初始化成功...");
		    handler.dealData(bfr, myConfig,iMonitor);
		}else{
		    //懒加载,内存优化
		    Alarm alarm = new Alarm(DateUtil.getDateTime(new Date()), "日志计算解析入库异常", "初始化数据库失败", bfore.getDealType().toString());
		    SelfAlarm.sendAlarm(alarm,null,null,"初始化数据库失败");
		}
		after.setDealEndTime(new Date());
		return after;
	}

	/* (non-Javadoc)
	 * @see com.iqiyi.dbagent.contraller.i.DBAgentTemplate#dealDataAsFile(java.util.List, com.iqiyi.dbagent.base.config.Configuration, com.iqiyi.dbagent.contraller.i.IDataStoreHandler)
	 */
	public DealAfter dealDataAsFile(List<String> fileList,
			Configuration config, IDataStoreHandler handler) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see com.iqiyi.dbagent.contraller.i.DBAgentTemplate#dealDataAsASCll(java.lang.Byte[], com.iqiyi.dbagent.base.config.Configuration, com.iqiyi.dbagent.contraller.i.IDataStoreHandler)
	 */
	public DealAfter dealDataAsASCll(Byte[] bytes, Configuration config,
			IDataStoreHandler handler) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see com.iqiyi.dbagent.contraller.i.DBAgentTemplate#dealDataAsText(java.lang.StringBuffer, com.iqiyi.dbagent.base.config.Configuration, com.iqiyi.dbagent.contraller.i.IDataStoreHandler)
	 */
	public DealAfter dealDataAsText(StringBuffer sbf, Configuration config,
			IDataStoreHandler handler) {
		// TODO Auto-generated method stub
		return null;
	}

    /* (non-Javadoc)
     * @see com.iqiyi.dbagent.base.i.IInitDataBase#showTable(java.lang.String)
     */
    public boolean showTable(String tabNames) {
        // TODO Auto-generated method stub
        return false;
    }

    /* (non-Javadoc)
     * @see com.iqiyi.dbagent.base.i.IInitDataBase#createTable(java.lang.String)
     */
    public boolean createTable(String tabNames) {
        // TODO Auto-generated method stub
        return false;
    }

    /* (non-Javadoc)
     * @see com.iqiyi.dbagent.base.i.IInitDataBase#showTables(java.util.Set)
     */
    public Map<String, Boolean> showTables(Set<String> tabNames) {
        // TODO Auto-generated method stub
        return null;
    }

    /* (non-Javadoc)
     * @see com.iqiyi.dbagent.base.i.IInitDataBase#createTables(java.util.Set)
     */
    public Map<String, Boolean> createTables(Set<String> tabNames) {
        // TODO Auto-generated method stub
        return null;
    }
    /* (non-Javadoc)
     * @see com.iqiyi.dbagent.base.i.IInitDataBase#initDataBase(java.util.Set)
     */
    public Map<String, Boolean> initDataBase(Set<String> sqls,Connection conn) {
        Map<String,Boolean> initRes = new ConcurrentHashMap<String, Boolean>();
        PreparedStatement pst = null;
        String currentSql = null;
        try {
            for(String sql:sqls){
                currentSql = sql;
                pst = conn.prepareStatement(sql);
                pst.execute();
                initRes.put(currentSql, true);
            }
        } catch (Exception e) {
            logger.error("初始化sql:{}数据库异常:{}",currentSql,e.getMessage());
            initRes.put(currentSql, false);
        }finally{
            if(null!=pst){
                try {
                    pst.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null!=conn){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return initRes;
    }

    /* (non-Javadoc)
     * @see com.iqiyi.dbagent.base.i.IInitDataBase#initDataBase(com.iqiyi.dbagent.base.config.i.Configuration)
     */
    public boolean initDataBase(Configuration config) {
        MySqlConfig myConfig = (MySqlConfig)config;
        Map<String,Table4QiData> tabMap = myConfig.getTableMap();
        Set<String> initSqlSet = new HashSet<String>();
        Connection conn = null;
        for(String key:tabMap.keySet()){
            List<String> sqls = tabMap.get(key).getSqls();
            if(null != sqls && !sqls.isEmpty()){
                initSqlSet.addAll(sqls);
                logger.info("初始化表:{}",key);
                //logger.info("初始化表:{},enty:{}",key,tabMap.get(key));
            }else{
                logger.warn("请检查:{},配置信息:{}",key,tabMap.get(key));
            }
        }
        try {
            conn = DataSourceUtil.getDataSource(DataSourceUtil.DRUID_MYSQL_SOURCE,MySqlConfig.getInstance()).getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(null != conn){
            Map<String,Boolean> initRes = initDataBase(initSqlSet,conn);
            for(String key:initRes.keySet()){
                if(!initRes.get(key)){
                    logger.error("初始化语句:{}失败!", key);
                    return false;
                }
            }
        }else{
            logger.error("初始化数据库连接失败!");
            return false;
        }
        return true;
    }

    /* (non-Javadoc)
     * @see com.iqiyi.dbagent.contraller.i.DBAgentTemplate#dealDataAsStreaming(java.io.InputStream, com.iqiyi.dbagent.base.config.i.Configuration, com.iqiyi.dbagent.contraller.i.IDataStoreHandler)
     */
    public DealAfter dealDataAsStreaming(InputStream is, Configuration config,
            IDataStoreHandler handler) {
        // TODO Auto-generated method stub
        return null;
    }

}
